package controllers

import (
	"backend/models"
	"backend/services"
	"net/http"

	"github.com/gin-gonic/gin"
)

type RoleControl struct {
	service *services.RoleService
}

type RoleForm struct {
	Name string `json:"name"`
	Desc string `json:"desc"`
}

type RoleResp struct {
	Name string `json:"name"`
	Desc string `json:"desc"`
	Id   uint   `json:"id"`
}

func NewRoleControl(s *services.RoleService) *RoleControl {
	return &RoleControl{service: s}
}

func (r *RoleControl) Create(c *gin.Context) {
	roleform := &RoleForm{}
	if err := c.ShouldBindJSON(roleform); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	modelform := &models.Role{Name: roleform.Name, Desc: roleform.Desc}
	if err := r.service.Create(modelform); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "message": "success", "data": RoleResp{
		Name: modelform.Name,
		Desc: modelform.Desc,
		Id:   modelform.ID,
	}})

}

func (r *RoleControl) Update(c *gin.Context) {
	id, err := models.GetParamsInt(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	roleform := &RoleForm{}
	if err := c.ShouldBindJSON(roleform); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	modelform := &models.Role{Name: roleform.Name, Desc: roleform.Desc}
	if err := r.service.Update(uint(id), modelform); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "message": "success", "update": RoleResp{
		Name: modelform.Name,
		Desc: modelform.Desc,
		Id:   modelform.ID,
	}})

}
func (r *RoleControl) Delete(c *gin.Context) {
	id, err := models.GetParamsInt(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	if err := r.service.Delete(uint(id)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "message": "success"})
}

func (r *RoleControl) GetList(c *gin.Context) {
	pageinfo, err := models.GetPageInfo(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
	}
	name := c.Query("name")
	m := &models.Role{Name: name}
	roles, total, err := r.service.GetList(pageinfo, m)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
	}
	rolesresp := []RoleResp{}
	for _, item := range roles {
		rolesresp = append(rolesresp, RoleResp{
			Name: item.Name,
			Desc: item.Desc,
			Id:   item.ID,
		})
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "message": "success", "data": rolesresp, "page": pageinfo.Page, "size": pageinfo.Size, "total": total})
}

type RolePermission struct {
	RoleID      uint   `json:"role_id"`
	Permissions []uint `json:"permission"`
}

func (r *RoleControl) SetRolePermission(c *gin.Context) {
	rolepermission := &RolePermission{}
	if err := c.ShouldBindJSON(rolepermission); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	if err := r.service.SetRolePermission(rolepermission.RoleID, rolepermission.Permissions); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"success": ""})

}

func (r *RoleControl) GetRolePermission(c *gin.Context) {
	id, err := models.GetParamsInt(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	resp, err := services.GetMenuTree([]uint{uint(id)}, false)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
	}
	c.JSON(http.StatusOK, gin.H{"data": resp})
}
